package com.chatplus.application.service.chat.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.dao.chat.ChatHistoryDao;
import com.chatplus.application.domain.entity.chat.ChatHistoryEntity;
import com.chatplus.application.service.chat.ChatHistoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Comparator;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 聊天历史记录业务逻辑实现
 *
 * <p>Table: t_chat_history - 聊天历史记录</p>
 *
 * @author developer
 * @see ChatHistoryEntity
 */
@Service
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryDao, ChatHistoryEntity> implements ChatHistoryService {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(ChatHistoryServiceImpl.class);

    @Override
    public ChatHistoryEntity getLastReplyHistoryByUserId(Long userId, String chatId) {
        return getOne(new LambdaQueryWrapper<>(ChatHistoryEntity.class)
                .eq(userId != null, ChatHistoryEntity::getUserId, userId)
                .eq(ChatHistoryEntity::getType, "reply")
                .eq(StringUtils.isNotEmpty(chatId), ChatHistoryEntity::getChatId, chatId)
                .orderByDesc(ChatHistoryEntity::getCreatedAt)
                .last("limit 1")
        );
    }

    @Override
    public List<ChatHistoryEntity> getChatContextHistoryList(Long userId, String chatId) {
        return list(new LambdaQueryWrapper<>(ChatHistoryEntity.class)
                .eq(userId != null, ChatHistoryEntity::getUserId, userId)
                .eq(StringUtils.isNotEmpty(chatId), ChatHistoryEntity::getChatId, chatId)
                .eq(ChatHistoryEntity::getUseContext, Boolean.TRUE)
                .orderByDesc(ChatHistoryEntity::getId)
        );
    }

    @Override
    public List<ChatHistoryEntity> getHistoryByItemId(Long historyItemId) {
        return list(new LambdaQueryWrapper<>(ChatHistoryEntity.class)
                .eq(ChatHistoryEntity::getItemId, historyItemId));
    }

    @Override
    public List<ChatHistoryEntity> getReplyHistoryList(Long userId) {
        return list(new LambdaQueryWrapper<>(ChatHistoryEntity.class)
                .eq(userId != null, ChatHistoryEntity::getUserId, userId)
                .eq(ChatHistoryEntity::getType, "reply")
                .orderByDesc(ChatHistoryEntity::getId)
        );
    }

    @Override
    public long getThisMonthToken(List<ChatHistoryEntity> replyHistoryList) {
        // replyHistoryList 根据 chatId 去重取createdAt最大的
        replyHistoryList = replyHistoryList.stream()
                .collect(Collectors.toMap(
                        ChatHistoryEntity::getChatId,
                        Function.identity(),
                        BinaryOperator.maxBy(Comparator.comparing(ChatHistoryEntity::getCreatedAt))
                ))
                .values()
                .stream()
                .toList();
        Instant now = Instant.now();
        Instant firstDayOfThisMonth = now.minus(Duration.ofDays(now.atZone(ZoneId.systemDefault()).getDayOfMonth() - 1L));
        return replyHistoryList.stream()
                .filter(chatHistoryEntity -> chatHistoryEntity.getCreatedAt().isAfter(firstDayOfThisMonth))
                .mapToLong(ChatHistoryEntity::getTokens).sum();
    }

    @Override
    public long getTotalToken(List<ChatHistoryEntity> replyHistoryList) {
        // replyHistoryList 根据 chatId 去重取createdAt最大的
        replyHistoryList = replyHistoryList.stream()
                .collect(Collectors.toMap(
                        ChatHistoryEntity::getChatId,
                        Function.identity(),
                        BinaryOperator.maxBy(Comparator.comparing(ChatHistoryEntity::getCreatedAt))
                ))
                .values()
                .stream()
                .toList();
        // 总的token
        return replyHistoryList.stream().mapToLong(ChatHistoryEntity::getTokens).sum();
    }
}
